﻿unit uRcdf.Arc.Classes;

interface

uses
  System.SysUtils, System.Classes, System.JSON, System.Generics.Defaults,
  System.Generics.Collections,

  uRcdf.Arc;

type

  /// <summary>
  ///   包装一些常用的类，和为 TArc 提供一些常用的构造这些类的方法
  ///   很奇怪，有的时候返回值用 type = 后的名字，会出现代码错误的
  ///   情况，这时用原始的写法就会好了。估计是 Delphi 的 Bug。
  /// </summary>

  IArcListString = IArcWarpper<TList<string>>;
  IArcListInteger = IArcWarpper<TList<Integer>>;
  IArcList<T> = interface;
  IArcMap<TK, TV> = interface;

  IArcJSONObject = IArcWarpper<TJSONObject>;
  IArcStringBuilder = IArcWarpper<TStringBuilder>;
  IArcListObject = IArcWarpper<TList<IInterface>>;

  TArcMake = class
  public
    class function MakeListString(aCapacity: Integer): IArcListString; overload;
    class function MakeListString(aList: TStrings): IArcListString; overload;

    class function MakeListInteger(aCapacity: Integer): IArcListInteger;

    class function MakeList<T>(aCapacity: Integer = 0): IArcList<T>; overload;
    class function MakeList<T>(const aCollection: TEnumerable<T>): IArcList<T>; overload;
    class function MakeList<T>(const aComparison: TComparison<T>): IArcList<T>; overload;

    class function MakeMap<TK, TV>(aCapacity: Integer = 0): IArcMap<TK, TV>; overload;
    class function MakeMap<TK, TV>(
      const aCollection: TEnumerable<TPair<TK, TV>>): IArcMap<TK, TV>;  overload;
    class function MakeMap<TK, TV>(aCapacity: Integer;
      const aEqualityComparison: TEqualityComparison<TK>;
      const aHasher: THasher<TK>): IArcMap<TK, TV>; overload;

      //    class function MakeMap<TK, TV>(aCapacity: Integer = 0): IArcMap<TK, TV>; overload;
//    class function MakeMap<TK, TV>(aCapacity: Integer = 0): IArcMap<TK, TV>; overload;

    class function MakeJSONObject(): IArcJSONObject; overload;
    class function MakeJSONObject(const aString: string): IArcJSONObject; overload;
    class function MakeStringBuilder(aCapacity: Integer): IArcStringBuilder;
    class function MakeListObject(aCapacity: Integer): IArcListObject;
  end;

  // ===========================================================================

  IArcList<T> = interface(IArcWarpper<TList<T>>)
  end;
  /// <summary> 引用计数的列表泛型 </summary>
  /// <remarks> 用来代替 IArcWarpper<TList<T>>，因为其写法太麻烦了.
  ///   .O 返回的 TList </remarks>
  TArcList<T> = class(TArcWarpper<TList<T>>, IArcList<T>)
  public
    constructor Create(aCapacity: Integer = 0); overload;
    constructor Create(const aCollection: TEnumerable<T>); overload;
    constructor Create(const aComparison: TComparison<T>); overload;
  end;

  // ===========================================================================

  IArcMap<TK, TV> = interface(IArcWarpper<TDictionary<TK, TV>>)
  end;
  /// <summary> 引用计数的Map泛型 </summary>
  /// <remarks> 用来代替 IArcWarpper<TDictionary<TK, TV>>，因为其写法太麻烦了.
  ///   .O 返回的 TDictionary </remarks>
  TArcMap<TK, TV> = class(TArcWarpper<TDictionary<TK, TV>>, IArcMap<TK, TV>)
  public
    constructor Create(aCapacity: Integer = 0); overload;
    constructor Create(const aCollection: TEnumerable<TPair<TK, TV>>); overload;
    constructor Create(aCapacity: Integer;
      const aEqualityComparison: TEqualityComparison<TK>;
      const aHasher: THasher<TK>); overload;
  end;

implementation

{ TArcMake }

class function TArcMake.MakeStringBuilder(
  aCapacity: Integer): IArcStringBuilder;
begin
  Result := TArc.Arc(TStringBuilder.Create(aCapacity));
end;

class function TArcMake.MakeJSONObject: IArcJSONObject;
begin
  Result := TArc.Arc(TJSONObject.Create);
end;

class function TArcMake.MakeJSONObject(const aString: string): IArcJSONObject;
var
  mJsonValue: TJSONValue;
begin
  mJsonValue := TJSONObject.ParseJSONValue(aString);
  if mJsonValue = nil then
    Result := nil
  else if not (mJsonValue is TJSONObject) then
  begin
    FreeAndNil(mJsonValue);
    Result := nil;
  end
  else
    Result := TArc.Arc(TJSONObject(mJsonValue));
end;

class function TArcMake.MakeList<T>(aCapacity: Integer): IArcList<T>;
begin
  Result := TArcList<T>.Create(aCapacity);
end;

class function TArcMake.MakeList<T>(
  const aCollection: TEnumerable<T>): IArcList<T>;
begin
  Result := TArcList<T>.Create(aCollection);
end;

class function TArcMake.MakeList<T>(
  const aComparison: TComparison<T>): IArcList<T>;
begin

end;

class function TArcMake.MakeListInteger(aCapacity: Integer): IArcListInteger;
begin
  Result := TArc.Arc(TList<Integer>.Create);
  Result.O.Capacity := aCapacity
end;

class function TArcMake.MakeListObject(aCapacity: Integer): IArcListObject;
begin
  Result := TArc.Arc(TList<IInterface>.Create);
  Result.O.Capacity := aCapacity
end;

class function TArcMake.MakeListString(aList: TStrings): IArcListString;
var
  i: Integer;
begin
  Result := MakeListString(aList.Count);
  for i := 0 to aList.Count - 1 do
    Result.O.Add(aList[i]);
end;

class function TArcMake.MakeListString(aCapacity: Integer): IArcListString;
begin
  Result := TArc.Arc(TList<string>.Create);
  Result.O.Capacity := aCapacity
end;

class function TArcMake.MakeMap<TK, TV>(aCapacity: Integer;
  const aEqualityComparison: TEqualityComparison<TK>;
  const aHasher: THasher<TK>): IArcMap<TK, TV>;
begin
  Result := TArcMap<TK, TV>.Create(aCapacity, aEqualityComparison, aHasher);
end;

class function TArcMake.MakeMap<TK, TV>(
  const aCollection: TEnumerable<TPair<TK, TV>>): IArcMap<TK, TV>;
begin
  Result := TArcMap<TK, TV>.Create(aCollection);
end;

class function TArcMake.MakeMap<TK, TV>(aCapacity: Integer): IArcMap<TK, TV>;
begin
  Result := TArcMap<TK, TV>.Create(aCapacity);
end;

{ TArcList<T> }

constructor TArcList<T>.Create(aCapacity: Integer);
var
  mList: TList<T>;
begin
  mList := TList<T>.Create;
  inherited CreateWarpper(mList);
  if aCapacity > 0 then
    mList.Capacity := aCapacity;
end;

constructor TArcList<T>.Create(const aComparison: TComparison<T>);
var
  mList: TList<T>;
begin
  mList := TList<T>.Create(TComparer<T>.Construct(aComparison));
  inherited CreateWarpper(mList);
end;

constructor TArcList<T>.Create(const aCollection: TEnumerable<T>);
var
  mList: TList<T>;
begin
  mList := TList<T>.Create(aCollection);
  inherited CreateWarpper(mList);
end;

{ TArcMap<TK, TV> }

constructor TArcMap<TK, TV>.Create(aCapacity: Integer);
var
  mMap: TDictionary<TK, TV>;
begin
  mMap := TDictionary<TK, TV>.Create(aCapacity);
  inherited CreateWarpper(mMap);
end;

constructor TArcMap<TK, TV>.Create(
  const aCollection: TEnumerable<TPair<TK, TV>>);
var
  mMap: TDictionary<TK, TV>;
begin
  mMap := TDictionary<TK, TV>.Create(aCollection);
  inherited CreateWarpper(mMap);
end;

constructor TArcMap<TK, TV>.Create(aCapacity: Integer;
  const aEqualityComparison: TEqualityComparison<TK>;
  const aHasher: THasher<TK>);
var
  mMap: TDictionary<TK, TV>;
begin
  mMap := TDictionary<TK, TV>.Create(aCapacity,
    TEqualityComparer<TK>.Construct(aEqualityComparison, aHasher));
  inherited CreateWarpper(mMap);
end;

end.
